﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DataGridViewDemo
{
    /**
     * DataGridView
     * AutoSizeColumnsMode: Fill  可见列宽度自适应
     * 窗体编辑列中选择某列的， FillWeight:50 列宽度占比
     * 固定按钮的两种设置:
     * 编辑列中:选择修改的按钮列,DefaultCellStyle点进去,设置NullValue:修改  (固定按钮文本)
     * 编辑列中：选择删除列的链接按钮Text:删除,UseColumnTextForLinkValue:true。这个设置运行时有数据才显示文本
     * 编辑列中选择年级列(DataGridViewComboboxColumn)的Items属性可以加入固定的选项值
     * 
     * 修改表头样式:
     * EnableHeadersVisualStyles: false  关闭表头主题样式，才能自定义表头样式
     * ColumnHeadersHeightSizeMode:EnableResizing 允许调整表头高度
     * ColumnHeadersHeight:35  设置表头高度
     * 
     * 列标题单元格样式设置:
     * ColumnHeadersDefaultCellStyle中设置BackColor=CadetBlue、Font=微软雅黑,9pt,style=Bold、ForeColor=White
     * 
     * ColumnHeadersBorderStyle:Single  设置表头边框样式
     * 
     * GridColor:ActiveCaption  设置网格线颜色
     * 
     * MutiSelect:false 是否允许多行,true允许,默认值
     * 
     * 
     * RowHeadersWidth:30  设置行头宽度
     * RowHeadersDefaultCellStyle中可以设置行头样式
     * RowsDefaultCellStyle:设置数据行单元格默认样式
     * 
     * 
     * SelectionMode:RowHeaderSelect  行选择模式默认为行头选择
     * 
     * AlternatingRowsDefaultCellStyle: 奇数行的默认单元格样式 (和默认行的单元格样式就可以设置出交替行的样式)
     * 
     * DataSource: 设置数据源:DataTable、List<T>
     * 
     * BackgroundColor:White  设置DataGridView背景颜色
     */
    public partial class Form1 : Form
    {
        DataTable gradeDataTable = new DataTable();

        DataTable classDataTable = new DataTable();

        List<ClassInfo> list = new List<ClassInfo>();

        public Form1()
        {
            InitializeComponent();


            gradeDataTable.Columns.Add("GradeId", typeof(int));
            gradeDataTable.Columns.Add("GradeName", typeof(string));

            gradeDataTable.Rows.Add(1, "一年级");
            gradeDataTable.Rows.Add(2, "二年级");
            gradeDataTable.Rows.Add(3, "三年级");

            //classDataTable.Columns.Add("ClassId", typeof(int));
            //classDataTable.Columns.Add("ClassName", typeof(string));
            //classDataTable.Columns.Add("GradeId", typeof(int));
            //classDataTable.Columns.Add("Remark", typeof(string));

            //classDataTable.Rows.Add(101, "一年级一班", 1, "这是备注信息1");
            //classDataTable.Rows.Add(102, "一年级二班", 1, "这是备注信息2");
            //classDataTable.Rows.Add(201, "二年级一班", 2, "这是备注信息3");
            //classDataTable.Rows.Add(202, "二年级二班", 2, "这是备注信息4");
            //classDataTable.Rows.Add(301, "三年级一班", 3, "这是备注信息5");


            list.Add(new ClassInfo() { ClassId = 101, ClassName = "一年级一班", GradeId = 1, Remark = "这是备注信息1" });
            list.Add(new ClassInfo() { ClassId = 102, ClassName = "一年级二班", GradeId = 1, Remark = "这是备注信息2" });
            list.Add(new ClassInfo() { ClassId = 201, ClassName = "二年级一班", GradeId = 2, Remark = "这是备注信息3" });
            list.Add(new ClassInfo() { ClassId = 202, ClassName = "二年级二班", GradeId = 2, Remark = "这是备注信息4" });
            list.Add(new ClassInfo() { ClassId = 301, ClassName = "三年级一班", GradeId = 3, Remark = "这是备注信息5" });



            //this.dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;

        }

        private void Form1_Load(object sender, EventArgs e)
        {

            #region 绑定

            // 绑定下拉框数据源(年级)，绑定数据前先绑定下拉框列的数据
            DataGridViewComboBoxColumn gridCol = dataGridView1.Columns["colGrade"] as DataGridViewComboBoxColumn;
            gridCol.DisplayMember = "GradeName";
            gridCol.ValueMember = "GradeId";
            gridCol.DataSource = gradeDataTable;

            // 绑定数据源
            dataGridView1.AutoGenerateColumns = false; // 不自动生成列
            //dataGridView1.DataSource = classDataTable;  // 如果我们的数据源是DataTable, 行数据类型就是一个DataRowView.Row --> DataRow
            dataGridView1.DataSource = list;  // 如果我们的数据源是List<T>, 行数据类型就是一个ClassInfo对象

            #endregion


        }

        List<int> selectedIds = new List<int>();

        /// <summary>
        /// 单元格点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            // 获取到操作单元格 ---> 内容,响应处理
            DataGridViewCell curCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];

            // 获取行绑定对象是List<T>是ClassInfo对象
            ClassInfo classInfo = dataGridView1.Rows[e.RowIndex].DataBoundItem as ClassInfo;

            // 这种方式可读性不好，性能也差涉及到拆箱，而且是弱类型的
            // 获取行绑定对象是DataTable是DataRowView ---> DataRow对象
            //DataRow dr = (dataGridView1.Rows[e.RowIndex].DataBoundItem as DataRowView).Row;

            if (curCell is DataGridViewCheckBoxCell)
            {
                // curCell.FormattedValue:格式化后单元格的值
                if (curCell.FormattedValue.ToString() == "True")
                {
                    // 获取选取行的编号
                    selectedIds.Add(classInfo.ClassId);

                    //selectedIds.Add((int)dr["ClassId"]);
                }
                else
                {
                    // 移除编号
                    selectedIds.Remove(classInfo.ClassId);
                }
            }
            else if (curCell.FormattedValue.ToString() == "修改")
            {
                // 修改响应处理
                MessageBox.Show("修改");
            }
            else if (curCell.FormattedValue.ToString() == "删除")
            {
                // 删除处理
                MessageBox.Show("删除");
            }

        }

        /// <summary>
        /// 单元格的状态因其内容改变而改变(让dataGridView1_CellContentClick事件立即获取到更改后的值,否则dataGridView1_CellContentClick事件将得不到最新改变的值,比如不添加此代码，这个datagridview复选框选中,CellContentClick事件中无法获取选中的值)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
        }

        /// <summary>
        /// 动态添加一行(用的少)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            // 注意: 这种方式添加行,要求DataGridView没有绑定数据源,否则会报错

            //// 添加行 --- 一行: 添加多个单元格  -- 行添加到Rows
            //DataGridViewRow dr = new DataGridViewRow();
            //// 添加各个单元格
            //DataGridViewCheckBoxCell chkCell = new DataGridViewCheckBoxCell();
            //chkCell.Value = false;
            //dr.Cells.Add(chkCell);

            //DataGridViewTextBoxCell idCell = new DataGridViewTextBoxCell();
            //idCell.Value = 1;
            //dr.Cells.Add(idCell);

            //DataGridViewTextBoxCell classNameCell = new DataGridViewTextBoxCell();
            //classNameCell.Value = "一班";
            //dr.Cells.Add(classNameCell);

            //// 获取列
            //DataGridViewComboBoxColumn gradeCol = dataGridView1.Columns["colGrade"] as DataGridViewComboBoxColumn;
            //// 单元格
            //DataGridViewComboBoxCell gradeCell = new DataGridViewComboBoxCell();
            //// 为单元格添加该列的可选项
            //gradeCell.Items.AddRange(gradeCol.Items);
            //gradeCell.Value = "2021级";
            //dr.Cells.Add(gradeCell);

            //DataGridViewTextBoxCell remarkCell = new DataGridViewTextBoxCell();
            //remarkCell.Value = "一班的备注";
            //dr.Cells.Add(remarkCell);

            //DataGridViewButtonCell btnCell = new DataGridViewButtonCell();
            //dr.Cells.Add(btnCell);

            //DataGridViewLinkCell linkCell = new DataGridViewLinkCell();
            //linkCell.UseColumnTextForLinkValue = true; // 使用列的文本值
            //dr.Cells.Add(linkCell);

            //dataGridView1.Rows.Add(dr);
        }
    }
}
